package com.example.demo.server.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.common.TypeEnum;
import com.example.demo.dto.UserDto;
import com.example.demo.mapper.UserMapper;
import com.example.demo.pojo.Minute;
import com.example.demo.pojo.Users;
import com.example.demo.pojo.Wallets;
import com.example.demo.server.UserService;
import com.example.demo.server.WalletService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl
        extends ServiceImpl<UserMapper, Users>
        implements UserService{

    @Autowired
    private WalletService walletService;

    /**
     * 按照用户id查询余额
     * @param id
     * @return
     */
    @Override
    public Double queryBalance(Integer id) {

        // 获取当前用户钱包对象
        // 构造条件语句
        Wallets wallets = getWallets(id);

        // 返回余额
        return wallets.getBalance();
    }

    /**
     * 消费100，涉及交易事务
     * @param id 用户id
     * @param money 消费金额
     * @return
     */
    @Override
    @Transactional
    public boolean consume(Integer id, Double money) {
        // 查询当前用户的钱包
        Wallets wallets = getWallets(id);
        // 插入钱包交易记录，类型为消费
        walletService.deal(wallets.getId(), money, wallets.getBalance(), TypeEnum.CONSUME.getType());
        // 修改钱包余额
        wallets.setBalance( wallets.getBalance()-money );
        boolean flag = walletService.updateById(wallets);

        return flag;
    }

    /**
     * 增加交易记录，退钱到用户钱包余额
     * @param id 用户id
     * @param money 变动金额
     * @return
     */
    @Override
    @Transactional
    public boolean refund(Integer id, Double money) {
        // 查询当前用户的钱包
        Wallets wallets = getWallets(id);
        // 插入钱包交易记录，类型为退款
        walletService.deal(wallets.getId(), money, wallets.getBalance(), TypeEnum.REFUND.getType());
        // 修改钱包余额
        wallets.setBalance( wallets.getBalance()+money );
        boolean flag = walletService.updateById(wallets);

        return flag;
    }

    /**
     * 根据用户id查询明显集合
     * @param id    用户id
     * @return  该用户所有明细
     */
    @Override
    @Transactional
    public List<UserDto> queryAllMinute(Integer id) {
        // 查询当前用户所有金额变动记录
        // 1.获取当前用户、获取钱包
        Wallets wallets = getWallets(id);
        Users user = this.getById(id);

        // 2.根据钱包id获取所有的明细变动
        LambdaQueryWrapper<Minute> lamb = new LambdaQueryWrapper<>();
        lamb.eq(Minute::getWallet_id, wallets.getId()); // 和钱包的id相等的记录
        List<Minute> minutes = walletService.getAllMinute(lamb);

        // 3. 封装记录，获取当前余额
        List<UserDto> userDtos = new ArrayList<>();
        // 遍历查询到的记录变化，消费或者退款时刻的钱包状态
        for (Minute minute : minutes) {
            // 创建对象
            UserDto userDto = new UserDto();
            // 拷贝相同部分，忽略金额属性
            BeanUtils.copyProperties(user, userDto);
            // 再设置变动明细
            userDto.setAmount(minute.getAmount());
            userDto.setBalance(minute.getBalance_at());

            // 查看是退款还是消费
            if (minute.getType().equals(TypeEnum.CONSUME.getType())){
                userDto.setType(TypeEnum.CONSUME.getMsg()); // 如果是消费，显示“消费”
            }else {
                userDto.setType(TypeEnum.REFUND.getMsg()); // 显示“退款”
            }

            // 放入集合
            userDtos.add(userDto);
        }

        return userDtos;
    }


    // 封装 根据用户id查询用户钱包
    public Wallets getWallets(Integer id){
        LambdaQueryWrapper<Wallets> lamb = new LambdaQueryWrapper<>();
        lamb.eq(Wallets::getUser_id, id);
        Wallets wallets = walletService.getOne(lamb);
        return wallets;
    }
}
